﻿// ===============================================================================
// ReferenceJoin.cs
// EOS Framework
// ===============================================================================
// Copyright (c) EOS Development Group. All rights reserved.
// ===============================================================================

namespace EOS.Framework.Contracts.Schema
{
    using System;

    /// <summary>
    /// Defines a join in a reference.
    /// </summary>
    [Serializable]
    public class ReferenceJoin : IEquatable<ReferenceJoin>
    {
        #region Properties

        /// <summary>
        /// The child column.
        /// </summary>
        private ColumnSchema _childColumn;

        /// <summary>
        /// Gets or sets the child column.
        /// </summary>
        /// <value>The child column.</value>
        public ColumnSchema ChildColumn
        {
            get { return _childColumn; }
            set { _childColumn = value; }
        }

        /// <summary>
        /// The parent columnn.
        /// </summary>
        private ColumnSchema _parentColumn;

        /// <summary>
        /// Gets or sets the parent column.
        /// </summary>
        /// <value>The parent column.</value>
        public ColumnSchema ParentColumn
        {
            get { return _parentColumn; }
            set { _parentColumn = value; }
        }

        /// <summary>
        /// The reference where this join belongs to.
        /// </summary>
        private ReferenceSchema _reference;

        /// <summary>
        /// Gets or sets the reference, where the join belongs to.
        /// </summary>
        /// <value>The reference the join belongs to.</value>
        public ReferenceSchema Reference
        {
            get { return _reference; }
            set { _reference = value; }
        }

        #endregion

        /// <summary>
        /// Initializes a new instance of the <see cref="ReferenceJoin"/> class.
        /// </summary>
        public ReferenceJoin()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ReferenceJoin"/> class
        /// with the parent columnd and the child column.
        /// </summary>
        /// <param name="parentColumn">The parent column.</param>
        /// <param name="childColumn">The child column.</param> 
        public ReferenceJoin(ColumnSchema parentColumn, ColumnSchema childColumn)
        {
            this._parentColumn = parentColumn;
            this._childColumn = childColumn;
        }

        /// <summary>
        /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
        /// </summary>
        /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param>
        /// <returns>
        /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
        /// </returns>
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return false;
            }

            return Equals(obj as ReferenceJoin);
        }

        /// <summary>
        /// Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <param name="other">An object to compare with this object.</param>
        /// <returns>
        /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
        /// </returns>
        public bool Equals(ReferenceJoin other)
        {
            if (other == null)
            {
                return false;
            }

            bool result = true;

            if (!Object.Equals(_childColumn, other._childColumn))
            {
                result = false;
            }

            if (!Object.Equals(_parentColumn, other._parentColumn))
            {
                result = false;
            }

            return result;
        }

        /// <summary>
        /// Serves as a hash function for a particular type.
        /// </summary>
        /// <returns>
        /// A hash code for the current <see cref="T:System.Object"/>.
        /// </returns>
        public override int GetHashCode()
        {
            int hashCode = 1;

            if (_childColumn != null)
            {
                hashCode ^= _childColumn.GetHashCode();
            }

            if (_parentColumn != null)
            {
                hashCode ^= _parentColumn.GetHashCode();
            }

            return hashCode;
        }
    }
}
